package icu.yougan.trade.service.Impl;

import icu.yougan.trade.entity.ChatMessage;
import icu.yougan.trade.entity.User;
import icu.yougan.trade.mapper.ChatMessageMapper;
import icu.yougan.trade.service.ChatService;
import icu.yougan.trade.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class ChatServiceImpl implements ChatService {
    private static final String RECENT_CHAT_PREFIX = "chat:recent:";
    private static final String UNREAD_COUNT_PREFIX = "chat:unread:";
    private static final long CACHE_EXPIRE_DAYS = 7;

    private final ChatMessageMapper chatMessageMapper;
    @Autowired
    private UserService userService;
    private final RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public ChatServiceImpl(ChatMessageMapper chatMessageMapper,
                           RedisTemplate<String, Object> redisTemplate) {
        this.chatMessageMapper = chatMessageMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    @Transactional
    public void saveMessage(ChatMessage message) {
        // 设置创建时间和时间戳
        if (message.getCreateTime() == null) {
            message.setCreateTime(new Date());
        }

        // 1. 存储到MySQL
        chatMessageMapper.insertChatMessage(message);

        // 2. 更新Redis未读计数
        if (!message.getSender().equals(message.getReceiver())) {
            String conversationKey = generateConversationId(message.getSender(), message.getReceiver());
            String unreadKey = UNREAD_COUNT_PREFIX + message.getReceiver();

            // 使用正确的会话标识并原子递增
            redisTemplate.opsForZSet().incrementScore(
                    unreadKey,
                    conversationKey,
                    1.0
            );
            redisTemplate.expire(unreadKey, CACHE_EXPIRE_DAYS, TimeUnit.DAYS);
        }
    }

    @Override
    public List<ChatMessage> getConversations(Long userId) {
        // 1. 从Redis获取最近会话
        String userRecentKey = RECENT_CHAT_PREFIX + userId;
        List<Object> recentChats = redisTemplate.opsForList().range(userRecentKey, 0, 99);

        // 2. 如果Redis没有，从MySQL获取
        if (recentChats == null || recentChats.isEmpty()) {
            return chatMessageMapper.selectRecentConversations(userId);
        }

        // 3. 转换类型并返回
        return recentChats.stream()
                .map(obj -> (ChatMessage) obj)
                .collect(Collectors.toList());
    }

    @Override
    public List<ChatMessage> getPrivateMessages(Long sender, Long receiver) {
        String cacheKey = RECENT_CHAT_PREFIX + generateConversationId(sender, receiver);
        List<Object> cachedMessages = redisTemplate.opsForList().range(cacheKey, 0, -1);

        if (cachedMessages != null && !cachedMessages.isEmpty()) {
            return cachedMessages.stream()
                    .map(obj -> (ChatMessage) obj)
                    .collect(Collectors.toList());
        }
        chatMessageMapper.batchUpdateReadStatusAndDeleteStatus(receiver);

        return chatMessageMapper.getPrivateMessages(sender, receiver);
    }

    @Override
    public List<ChatMessage> getItemMessages(Long itemId) {
        String cacheKey = RECENT_CHAT_PREFIX + "item_" + itemId;
        List<Object> cachedMessages = redisTemplate.opsForList().range(cacheKey, 0, -1);

        if (cachedMessages != null && !cachedMessages.isEmpty()) {
            return cachedMessages.stream()
                    .map(obj -> (ChatMessage) obj)
                    .collect(Collectors.toList());

        }

        return chatMessageMapper.getItemMessages(itemId);
    }

    @Override
    public void markMessagesAsRead(String sessionKey,Long Id) {
        chatMessageMapper.batchUpdateReadStatusAndDeleteStatus(Id);
        // 4. 清理Redis未读数
        String unreadKey = UNREAD_COUNT_PREFIX + Id;
        Set<Object> members = redisTemplate.opsForZSet().range(unreadKey, 0, -1);
        members.forEach(member -> System.out.println("Member: [" + member + "], Length: " + member.toString().length()));

        System.out.println("Redis中未读的数为："+unreadKey);
        System.out.println("获取sessionKey的值为:"+sessionKey);
        redisTemplate.opsForZSet().remove(
                unreadKey,
                sessionKey // 使用完整会话标识
        );
        System.out.println("执行标记");
    }

    private String getConversationKey(ChatMessage message) {
        return message.getItemId() != null ? RECENT_CHAT_PREFIX + "item_" + message.getItemId()
                : RECENT_CHAT_PREFIX + generateConversationId(message.getSender(), message.getReceiver());
    }

    private String generateConversationId(Long user1, Long user2) {
        if (user1 == null || user2 == null) {
            throw new IllegalArgumentException("用户ID不能为null");
        }
        // 按字母序排序保证唯一性
        Long[] users = {user1, user2};
        Arrays.sort(users);
        return "private_" + users[0] + "_" + users[1];
    }

    @Override
    public List<ChatMessage> getPrivateConversations(Long userId) {
        // 获取数据库中的基础会话数据
        List<ChatMessage> conversations = chatMessageMapper.selectRecentConversations(userId);
        // 如果没有会话记录，返回空列表
        if (conversations == null || conversations.isEmpty()) {
            return new ArrayList<>();
        }

        // 从 Redis 获取未读消息计数
        String unreadKey = UNREAD_COUNT_PREFIX + userId;
        Set<ZSetOperations.TypedTuple<Object>> unreadEntries = redisTemplate.opsForZSet().rangeWithScores(unreadKey, 0, -1);
        //System.out.println("从redis中历史获取未读消息值为:"+unreadKey+"    实体类为:"+unreadEntries);
        // 处理未读消息数
        Map<String, Integer> unreadCounts = new HashMap<>();
        if (unreadEntries != null) {
            for (ZSetOperations.TypedTuple<Object> entry : unreadEntries) {
                if (entry.getValue() != null && entry.getScore() != null) {
                    unreadCounts.put((String) entry.getValue(), entry.getScore().intValue());
                }
            }
        }

        //组装数据
        List<ChatMessage> result = new ArrayList<>();
        User user = userService.getUser(userId);
        for (ChatMessage conv : conversations) {
            // 确定对方用户 ID
            Long otherUser = userId.equals(conv.getSender()) ? conv.getReceiver() : conv.getSender();
            if (otherUser == null) {
                continue;
            }
            User user1 = userService.getUser(otherUser);
            // 生成会话唯一标识
            String convKey = generateConversationId(userId, otherUser);
            int unread = unreadCounts.getOrDefault(convKey, 0);
            // 复制数据到 DTO
            ChatMessage dto = new ChatMessage();
            BeanUtils.copyProperties(conv, dto);
            dto.setReceiverName(user1.getNickname());
            dto.setSenderName(user.getNickname());
            dto.setSenderAvatar(user.getAvatar());
            dto.setReceiverAvatar(user1.getAvatar());
            dto.setUnreadCount(unread);
            result.add(dto);
        }

        return result;
    }

    @Override
    @Transactional
    public boolean deleteConversations(List<Long> ids, Long senderId, Long receiveId,Long deleteUserId) {
        if(ids.isEmpty())
        {
            return false;
        }
        //先采用单项软删除
        chatMessageMapper.updateDeleteUserId(ids, deleteUserId);
        //如果符合标准，进行硬删除
        if(chatMessageMapper.getDeleteIsTrue(ids))
        {
            //System.out.println("当前要删除的消息为"+ids);
            redisTemplate.delete(RECENT_CHAT_PREFIX+"private_" + senderId+"_"+receiveId);
            return chatMessageMapper.deleteConversations(ids);
        }
        else return true;
    }

}